package com.chenjian.annotation.custom;

import com.chenjian.annotation.dao.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.ConcurrentHashMap;

public class DefaultCustomBeenFactory implements CustomBeenFactory {

    private static DefaultCustomBeenFactory defaultCustomBeenFactory = new DefaultCustomBeenFactory();

    private DefaultCustomBeenFactory() {
    }

    public static DefaultCustomBeenFactory getInstance() {
        return defaultCustomBeenFactory;
    }

    @Override
    public Object getBean(Object object) {
        Class<?> aClass = object.getClass();
        Object proxy;
        Class<?>[] interfaces = aClass.getInterfaces();
        //根据是否实现接口选择不同的代理方法
        if (interfaces.length > 0) {
            //实现了接口，jdk代理
            proxy = getJdkProxy(object);
        } else {
            //未实现接口，cglib代理
            proxy = getCgLibProxy(object);
        }
        return proxy;
    }

    //jdk代理
    public Object getJdkProxy(Object object) {
        Class<?>[] interfaces = object.getClass().getInterfaces();
        Object instance = Proxy.newProxyInstance(object.getClass().getClassLoader(), interfaces, new InvocationHandler() {
            //代理对象执行方法时执行的代理方法，实现增强逻辑
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                ConcurrentHashMap<String, Object> hashMap = CustomContext.getCustomContext().getCustomContextMap();
                //从been池中可以获取连接池管理对象，获取连接
                TransactionManager transactionManager = (TransactionManager) hashMap.get(TransactionManager.class.getName());
                //开启手动事务，主要是获取事务控制权限
                transactionManager.beginTransaction();
                Object invoke = null;
                try {
                    //执行原来逻辑
                    invoke = method.invoke(object, args);
                    //未抛出异常时候提交事务
                    transactionManager.commit();
                } catch (Exception e) {
                    //捕获异常，立即回滚事务
                    System.out.println("正在回滚事务");
                    transactionManager.rollback();
                    //同时抛出异常
                    throw e;
                }
                return invoke;
            }
        });
        return instance;
    }

    //cglib代理

    public Object getCgLibProxy(Object object) {

        Object o = Enhancer.create(object.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                ConcurrentHashMap<String, Object> hashMap = CustomContext.getCustomContext().getCustomContextMap();
                //从been池中可以获取连接池管理对象，获取连接
                TransactionManager transactionManager = (TransactionManager) hashMap.get(TransactionManager.class.getName());
                //开启手动事务，主要是获取事务控制权限
                transactionManager.beginTransaction();
                Object invoke = null;
                try {
                    //执行原来逻辑
                    invoke = method.invoke(object, objects);
                    //未抛出异常时候提交事务
                    transactionManager.commit();
                    System.out.println("正常提交事务");
                } catch (Exception e) {
                    //捕获异常，立即回滚事务
                    System.out.println("正在回滚事务");
                    transactionManager.rollback();
                    //同时抛出异常
                    throw e;
                }
                return invoke;
            }
        });
        return o;
    }
}
